//
// C++ Interface: BasicViewer
//
// Description: widget class to display a scene of geometric objects, using OpenGL, interface
//
// Author: Burkhard Lehner <lehner@informatik.uni-kl.de>, (C) 2006

#ifndef _GLBOX_H_
#define _GLBOX_H_

#include <QtOpenGL>
// The line below is for non-Mac computers.
#include <GL/glu.h>
// The line below is for Mac computers.
//#include <glu.h>


#include <QMouseEvent>
#include <QWheelEvent>
#include <vector>
//#include "renderobject.h"
#include <QString>
#include "Vector.h"
#include "Matrix.h"

class GLBox : public QGLWidget
{
    Q_OBJECT

public:
    // constructor, creates an OpenGL widget as a subwidget of "parent"
    GLBox( QWidget* parent, const QGLWidget* shareWidget = 0 );
    // destructor, deletes all objects of the scene
    ~GLBox();
    // adds an object to the scene
    // Attention: GLBox takes over responsibility for the object! It has to be created with "new"!
    //void addRenderObject (RenderObject *o);

public slots:
    // sets the mouse mode to "selection mode" (clicking an object emits signal objectSelected)
    void setPickingMode();
    // sets the mouse mode to "move mode" (rotating, translating and zooming the scene)
    void setMovingMode();

signals:
    // this signal is emitted whenever an object is clicked while in selection mode
    // the selected object is given as parameter, or the NULL pointer if no object was clicked
    //void objectSelected (RenderObject *);

protected:

    // Draws a line from point (ax,ay) to point (bx,by) with line width "width" and color (r,g,b)
    void paintLine(double ax, double ay, double bx, double by, double width, double r, double g, double b);

    // Draws a cross of size "size" and color (r,g,b) with center at (x,y)
    void paintPoint(double x, double y, double size, double r, double g, double b);

    void initPoints1();
    void initPoints2();
    void initPoints3();
    void initPoints4();

    std::vector<double> lagrangeInterpolation(std::vector<Vector> points);

    std::vector<Vector> evaluateLagrange(std::vector<double> interpolant, double xRangeStart, double xRangeEnd, uint numberPoints);

    std::vector<double> leastSquaresFit(std::vector<Vector> points, unsigned int degree);

    std::vector<Vector> evaluate(std::vector<double> coefficients, double xrange1, double xrange2, unsigned int numberPoints);

    void paintPolynomial(std::vector<Vector> points, double width, double r, double g, double b);


    // methods to deal with OpenGL stuff
    void initializeGL();
    void paintGL();
    void resizeGL( int w, int h );

    // methods to deal with events from the mouse and the mouse wheel
    void mouseMoveEvent (QMouseEvent *);
    void mousePressEvent (QMouseEvent *);
    void mouseReleaseEvent (QMouseEvent *);
    void wheelEvent (QWheelEvent *);

private:
    // stores whether we are in picking mode (true) or in moving mode (false)
    bool pickingMode;

    // helping method for picking (selecting an object with the mouse)
    //RenderObject *findObject (int x, int y);

    // current viewing transformation
    double ViewMatrix[16];  // transformation matrix
    double scale;   // zoom factor

    // value of the last mouse cursor position, needed for rotating, translating, etc.
    double x0, y0;

    // this array stores a list of all objects in the scene
    //std::vector <RenderObject*> objects;

    std::vector<Vector> m_points1;
    std::vector<Vector> m_points2;
    std::vector<Vector> m_points3;
    std::vector<Vector> m_points4;
    std::vector<Vector> m_draw;
    std::vector<double> m_coefficients;
    std::vector<Vector> m_polynomial;
};

#endif // _GLBOX_H_
